﻿namespace FsWeb.Controllers
open System.Collections.Generic
open System.Web
open System.Web.Mvc
open System.Net.Http
open System.Web.Http
open AttributeRouting;
open AttributeRouting.Web;
open AttributeRouting.Web.Http
open System.Diagnostics
open System
open FsWeb.Models
open System.Linq
open Business
open BusinessDomain
open WebMatrix.WebData

//open NewBusiness
//open MongoDB.Driver
//open MongoDB.Bson
//type searchResult = { title: string; host_url: string; link:string; favicon:string; description:string; tags : string array; printscreen:string; }

[<RoutePrefix("/api/Search")>]
type SearchController(bc:IBusinessContext) =
 inherit ApiController()
 [<HttpGet;GET("ByTags/{tags}?{?skip:int}")>]
 member s.ByTags (tags:string) (skip:int)  = 
     let skipNumber = skip
     let func:Async<Data.Url seq> = async {
        let! tagsIdArr = bc.TagContext.GetIdForTagsAsync [|tags|]
        return bc.BookmarksContext.Query(fun x -> query { for t in x do 
                                                                      where (tagsIdArr.Contains(t.TagId)) 
                                                                      groupBy t.Url into g
                                                                      where (g.Count() = tagsIdArr.Length)
                                                                      sortByDescending g.Key.position 
                                                                      skip skipNumber
                                                                      select g
                                                                      take 16
                                                                    }) |> Seq.map( fun g -> g.Key)
//                                                                                    new Data.ViewModels.UriVM(
//                                                                                             Id = g.Key.Id,
//                                                                                             Uri = g.Key.URI,
//                                                                                             HostUri = g.Key.HostUrl,
//                                                                                             favicon = g.Key.Favicon,
//                                                                                             Title = g.Key.Title,
//                                                                                             Description = g.Key.Description,
//                                                                                             isFile = g.Key.isFile,
//                                                                                             Image = g.Key.PrintScreenUri,
//                                                                                             position = g.Key.position
//                                                                                             ))
     }
     Async.RunSynchronously func |> Seq.map( fun u -> new Data.ViewModels.UriVM(Tags = u.Bookmarks.OrderByDescending(fun (b:Data.Bookmark) -> b.position).Take(5).Select(fun (b:Data.Bookmark) -> new Data.ViewModels.Tag(Id = b.Tag.Id, tag = b.Tag.TAG)).ToArray(), 
                                                                                    Id = u.Id, Uri = u.URI, HostUri = u.HostUrl, favicon = u.Favicon, Title = u.Title, Description = u.Description, isFile = u.isFile, Image = u.PrintScreenUri, position = u.position))
 [<AuthorizeAttribute>]
 [<HttpGet;GET("ByUserTags/{tags}?{?skip:int}")>]
 member s.ByUserTags (tags:string) (skip : int) = 
     let getUserTitle (ur:Data.Url) =  bc.UserContext.GetUser s.User.Identity.Name  |> fun us -> ur.UserUrlSettings.FirstOrDefault(fun (uus:Data.UserUrlSettings) -> uus.UserId = us.Id) |> fun us -> if us <> null then us.Title else ""
     let skipNumber = skip
     let func:Async<Data.Url seq> = async {
        let! tagsIds = bc.TagContext.GetIdForTagsAsync [|tags|]
        let usName = s.User.Identity.Name |> bc.UserContext.GetUser
        let! iq = bc.SeachContext.SearchInUserScope usName.Id tagsIds 
        return iq |> fun x -> query { for u in x do
                                        skip skipNumber
                                        take 16 } :> Data.Url seq
      }
     
     Async.RunSynchronously func |> Seq.map (fun u -> 
         new Data.ViewModels.UriVM(Tags = u.Bookmarks.OrderByDescending(fun (b:Data.Bookmark) -> b.position).Take(5).Select(fun (b:Data.Bookmark) 
                                                                                                                                -> new Data.ViewModels.Tag(Id = b.Tag.Id, tag = b.Tag.TAG)).ToArray(), 
                 Id = u.Id,
                  Uri = u.URI,
                   HostUri = u.HostUrl,
                    favicon = u.Favicon,
                     Title = (if s.User.Identity.IsAuthenticated then 
                                  getUserTitle u 
                                   else u.Title) ,
                                     Description = u.Description, isFile = u.isFile, Image = u.PrintScreenUri, position = u.position))
//     let skipNumber = skip
//     let userId = WebSecurity.CurrentUserId
//     let! tagsIdArr = bc.TagContext.GetIdForTagsAsync [|tags|]
//     return bc.BookmarksContext.Query(
//     fun x -> query {
//       for t in x do
//       where (query { for u in t.UserBookmarks do select  }
//       select t.Url
//     })
//     }
//     let func:Async<Data.Url seq> = async {
//       bc.BookmarksContext.Query( fun x -> query {
//           for t in x do ->
//              for u in t.UserBookmarks do ->
//              
//          })
//     let res = urls |> Seq.map (fun u -> bc.TagContext.GetTagsForUrlAsync u.Id) 
//                    |> Async.Parallel 
//                    |> Async.RunSynchronously 
//                    |> Array.map (fun x -> Array.fold (fun (uid,tgs) tg -> (uid, (snd tg)::tgs)) (fst (x.First()),[]) x)
//     "a"
     //urls |> Seq.map ( fun u -> u.Tags <- ((Array.find( fun t -> (fst t) = u.Id) res) 
                                                 //|> snd |> List.map (fun dt -> new Data.ViewModels.Tag( Id = dt.Id, tag = dt.TAG)) ))


//     let ret = bc.BookmarksContext.Query(fun x -> query { for b in x do 
//                                                          sortBy b.position 
//                                                          skip skipNumber 
//                                                          select b 
//                                                          take 10} ) |> Array.ofSeq
//     ret |> Array.map( fun b -> (Data.ViewModels.UriVM(Id = b.Url.Id, Uri = b.Url.URI, HostUri = b.Url.HostUrl, favicon = b.Url.Favicon, Title = b.Url.Title, Description = b.Url.Description, isFile = b.Url.isFile, Image = b.Url.PrintScreenUri, position = b.Url.position,
//                                                                                                 Tags = [
//                                                                                                       Data.ViewModels.Tag(Id = 0L,tag="tag1")
//                                                                                                       Data.ViewModels.Tag(Id = 1L,tag="tag2")
//                                                                                                       Data.ViewModels.Tag(Id = 3L,tag="tag3")
//                                                                                                       Data.ViewModels.Tag(Id = 4L,tag="tag4")
//                                                                                                       Data.ViewModels.Tag(Id = 5L,tag="tag5")
//                                                                                                       Data.ViewModels.Tag(Id = 6L,tag="tag6")
//                                                                                                                           ])
//                                                                                                     )
//                                                                               )
//     let mutable s  = tags;
//     Debug.Print(tags.Length.ToString());
//     let curs = bc.UrlContext.GetUrlsByTags(s);
//     curs.Skip <- skip
//     curs.Limit <- 10
//     curs.Fields <- FieldsDocument([BsonElement("_id", BsonInt32(1));BsonElement("tags",BsonInt32(1))])
//     seq {for x in curs do yield x.ToString()}
//     "hi"
//     let qweqweqwe = ""
//     seq { for x in [1..10] do yield {title = "Title" ; host_url = "http://example.com"; link = "http://example.com/myLink_" + x.ToString(); favicon = @"http://megogo.net/favicon.ico"; description = "Описание здесь"; tags = [|"tag1"; "tag2"; "tag3";"tag4"; "lonlonglonglongtag5"|];printscreen = @"http://placehold.it/500x750&text==" + x.ToString() }  }
